
#include <rtthread.h>

#include "phy_trans.h"
#include "net_trans.h"

/* 栈大小 */
#define PHY_STACK_SIZE					1024

/* 优先级 */
#define PHY_THREAD_PRIORITY				25

/* 时间片大小 */
#define PHY_THREAD_TIMESLICE			5

/* 串口数据最大缓存长度 */
#define PHY_BUFFER_MAX_LEN				700

ALIGN(RT_ALIGN_SIZE)
static char phy_stack[PHY_STACK_SIZE];
static struct rt_thread phy_thread;

/* 串口对象 */
static rt_device_t serial4;
/* 串口接受同步信号量 */
static struct rt_semaphore rx_sem;

/* 串口接收缓存 */
static char phy_buffer[PHY_BUFFER_MAX_LEN];
static rt_size_t phy_buffer_size;

//extern char g_server_data[];
//extern rt_size_t g_server_data_len;

/* 接收数据回调函数 */
static rt_err_t uart4_input(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    rt_sem_release(&rx_sem);
    return RT_EOK;
}

static void phy_port_init(void)
{
	rt_err_t ret = RT_EOK;
    
    serial4 = rt_device_find("uart4");
	RT_ASSERT(serial4 != NULL);

	/* 初始化串口接收同步信号 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);

    /* 以中断接收及轮询发送模式打开串口设备 */
    ret = rt_device_open(serial4, RT_DEVICE_FLAG_INT_RX);
	RT_ASSERT(ret == RT_EOK);

    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial4, uart4_input);
}

static void phy_recv_poll(void)
{
	char ch;
	rt_err_t err;

	while (1)
	{
		if (rt_device_read(serial4, -1, &ch, 1) == 1)
		{
			phy_buffer[phy_buffer_size++] = ch;

			if (phy_buffer_size > PHY_BUFFER_MAX_LEN)
			{
				rt_kprintf("meter data unexpect too long..\n");
				phy_buffer_size = 0;
			}
		}
		else
		{
			static char timeouttimes = 0;

			/* 500ms没有收到数据时将缓存的数据发送给服务器 */
            err = rt_sem_take(&rx_sem, rt_tick_from_millisecond(500));

			if (err != RT_EOK)
			{
				if (phy_buffer_size == 0)
				{
					timeouttimes++;

					//if (timeouttimes == 6)
					//{
					//	if (g_server_data_len != 0)
					//	{
					//		rt_kprintf("retrans server data to meter\n");
					//		rt_device_write(serial4, 0, g_server_data, g_server_data_len);
					//	}

					//	timeouttimes = 0;
					//}
				}
				else
				{
					//timeouttimes = 0;
					//g_server_data_len = 0;

					/* 打印缓存数据 */
					rt_kprintf("send %u bytes phy data to net\n", phy_buffer_size);
					//for (int i=0; i<phy_buffer_size; i++)
					//{
					//	rt_kprintf("%02x ", phy_buffer[i]);
					//}
					//rt_kprintf("\n");

					net_send(phy_buffer, phy_buffer_size);

					/* 服务器在线状态, 将缓存到的数据转发给服务器 */
					//if (get_net_status() == NET_CONNECTED)
					//{
					//	rt_kprintf("transmit meter data to server\n");
					//	tcp_send(phy_buffer, phy_buffer_size);
					//}
					//else
					//{
					//	rt_kprintf("device not online, cant trans meter data\n");
					//}

					phy_buffer_size = 0;
				}
			}
			else
			{
				timeouttimes = 0;
				// 正在连续读取数据, 不处理
			}
		}
	}
}

void phy_send(char const *buffer, rt_size_t len)
{
	rt_device_write(serial4, 0, buffer, len);
}

/* 线程入口 */
static void reader_entry(void *param)
{
    rt_kprintf("phy_thread begin\n");
	
	phy_recv_poll();
}

void phy_trans_start(void)
{
	phy_port_init();

    rt_thread_init(&phy_thread,
                   "phy_thread",
                   reader_entry,
                   RT_NULL,
                   &phy_stack[0],
                   sizeof(phy_stack),
                   PHY_THREAD_PRIORITY - 1, PHY_THREAD_TIMESLICE);

    rt_thread_startup(&phy_thread);
}

